require 'rubygems'
#require 'oauth'
require 'simple-oauth'
require 'json'

#プロフィール画像の変更用
require 'open-uri'
require 'net/http'
require 'cgi'

#require 'httpclient'

class TwitterClass

	@@debug=true
	@@format='json'

	def initialize(con_key,con_secret,ac_token,ac_token_secret,twitpic_api_key='')
		@access_token = SimpleOAuth.new(con_key,con_secret,ac_token,ac_token_secret)
		@twitpic_api_key = twitpic_api_key
	end

##特殊なもの
	#メッセージをツィートする。
	def update(message='')
		return false if (message=='')
		begin
			response = @access_token.post('http://twitter.com/statuses/update.json', 'status'=> message)
		rescue => err
			print_error('update',err,"failed to update [status]#{message}")
			return false
		end
		retrun_message=JSON.parse(response.body)
		return false  if (retrun_message['text'] != message)
		return true
	end

	#ダイレクトメッセージを送る
	def send_direct(to_user='',message='')
		return false if (to_user=='' or message=='')
		begin
			response = @access_token.post('http://twitter.com/direct_messages/new.json','user'=>to_user,'text'=>message)
		rescue => err
			print_error('send_direct',err,"failed to send [to]#{to_user} [text]#{message}")
			return false
		end
		retrun_message=JSON.parse(response.body)
		return false  if (retrun_message['text'] != message)
		return true
	end

	# プロフィール画像変更。
=begin
	def change_profile_image(image_path)
		result=nil
		if (File.exist?(image_path)) then
			url = URI.parse('http://twitter.com/account/update_profile_image.json')
			request = Net::HTTP::Post.new(url.request_uri)
			boundary = Time.now.strftime("%Y%m%d_%H%M%S_#{$$}")
			body_part=[]

			#Oauth追加
#			realm_url = "http://api.twitter.com/"
#			auth_provider_url = "https://api.twitter.com/1/account/verify_credentials.json"
#			add_oauth_echo_heder(request,realm_url,auth_provider_url)


			#画像追加
			add_file_body(body_part,boundary,'media',image_path)
			body_part << "--#{boundary}--"
			body_part << ""

			#body作成
			request.body = body_part.join("\r\n")

			request["Content-Length"] = request.body.size

			#送信
		else
			time = Time.now.strftime("%Y/%m/%d %H:%M:%S")
			puts "#{time}\t[Error:update]\t #{image_path} is not exist"
			return nil
		end
		return result.body
	end
=end

##POSTメソッド
	def post_message(method,value)
		response = nil
		url='http://twitter.com/'+method+'/'+"#{value}."+@@format
		begin
			response =  @access_token.post(url)
		rescue => err
			print_error('post_message',err,"failed #{method}")
		end
		return response
	end
	
	#tweet_idをReTweet
	def retweet(tweet_id)
		return post_message('statuses/retweet',tweet_id)
	end
	
	#tweet_idをお気に入り登録
	def favorite(tweet_id)
		return post_message('favorites/create',tweet_id)
	end
	
	#user_idをフレンドに（フォローする）
	def follow(user_id)
		return post_message('friendships/create',user_id)
	end
	
	#user_idをフレンドからはずす（アンフォローする）
	def unfollow(user_id)
		return post_message('friendships/destroy',user_id)
	end

##GETメソッド
	#GETのテンプレート
	#'http://twitter.com/"method".json'?"option" の値を返す
	def get_message(method,option='')
		response = nil
		url='http://twitter.com/'+method+'.'+@@format
		url = url+'?'+option if(option!='')
		puts url if(@@debug)
		begin
			response = @access_token.get(url)
		rescue => err
			print_error('get_message',err,"failed #{method}")
		end
		return response
	end

	#パブリックタイムラインを取得（count個）
	#返り値はstatus
	def get_public_timeline()
		return get_message('statuses/public_timeline')
	end

	#タイムラインを取得（自分も含む）
	#返り値はstatus
	def get_timeline(option='')
		return get_message('statuses/friends_timeline',option)
	end

	#タイムラインを取得（自分の分だけ）
	#返り値はstatus
	def get_my_timeline(option='')
		return get_message('statuses/user_timeline',option)
	end

	#自分がフォローしてる人の一覧を取得
	#返り値はusers
	def get_friends(option='')
		return get_message('statuses/friends',option)
	end

	#フォローしてくれてる人の一覧を取得
	#返り値はusers
	def get_followers(option='')
		return get_message('statuses/followers',option)
	end
	
	#ダイレクトメッセージの一覧を取得
	#返り値はdirect-messages
	def get_directmessage(option='')
		return get_message('direct_messages',option)
	end

##補助関数
	#statusの中身を全出力
	def dump_status_data(status)
		posted_user = status['user']
		puts ">> #{status['id']} - #{status['created_at']}"
		puts "\t #{status['text']}"
		puts "\t\t #{posted_user['id']}:#{posted_user['name']}(#{posted_user['screen_name']})"  if(posted_user!=nil)
		puts "\t\t   @#{posted_user['location']}:#{posted_user['url']}" if(posted_user!=nil)
	end
	
	#userの中身を全出力
	def dump_user_data(user)
		latest_status = user['status']
		puts ">> #{user['id']} - #{user['created_at']}"
		puts "\t #{user['name']}@#{user['location']}"
		puts "\t #{user['description']}"
		puts "\t image:#{user['profile_image_url']}"
		puts "\t URL:#{user['url']}"
		puts "\t\t #{latest_status['id']} - #{latest_status['created_at']}" if(latest_status!=nil)
		puts " \t\t"#{latest_status['text']}" if(latest_status!=nil)
	end

	#messagesの中身を全出力
	def dump_directmessage_data(message)
		sender_info=message['sender']
		recipient_info=message['recipient']
		puts ">> #{message['id']} - #{message['created_at']}"
		puts "\t To #{message['recipient_screen_name']}(#{message['recipient_id']})"
		puts "\t From #{message['sender_screen_name']}(#{message['sender_id']})"
		puts "\t #{message['text']}"
	end

	#アカウント設定の変更
	#2010/6/7 現在　非公式API
	#返り値はHTLMなので成功か失敗かは自分で判定する
	def account_setting(user)
		begin
			response = @access_token.post('http://twitter.com/account/settings', 'user' => user)
		rescue => err
			print_error('account_setting',err)
		end
		return response
	end

	#リクエストにOAuth Echo用のヘッダを追加
	def add_oauth_echo_heder(request,realm_url,auth_provider_url)
		auth = @access_token.make_auth_header(:GET, auth_provider_url)
		request["X-Auth-Service-Provider"] = auth_provider_url
		request["X-Verify-Credentials-Authorization"] = auth + ", realm=\"#{realm_url}\""
	end

	#リクエストBodyの配列に情報を追加
	def add_form_body(body_array,boundary,key,value)
		body_array << "--#{boundary}"
		body_array << "Content-Disposition: form-data; name=\"#{key}\""
		body_array << ""
		value.split(/\n/).each{|line|
			body_array << "#{line}"
		}
	end
	
	#リクエストBodyの配列にバイナリファイルの情報を追加
	def add_file_body(body_array,boundary,key,file_path)
		file_name = File.basename(file_path)
		mime_type = mime_type(file_name)
		body_array << "--#{boundary}"
		body_array << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{file_name}\""
		body_array << "Content-Type: #{mime_type}"
		body_array << ""
		open(file_path){|io|
			body_array << io.read
		}
	end

	#MIMEタイプを調べる
	def mime_type(file)
  	case 
    	when file =~ /\.jpg/ then 'image/jpg'
    	when file =~ /\.gif$/ then 'image/gif'
   		when file =~ /\.png$/ then 'image/png'
    	else 'application/octet-stream'
  	end
	end

#### TwitPic関数
	#http://postcard.blog.ocn.ne.jp/itazura/2010/05/twitpic_api_v2_.html
	def twitpic_upload(image_file_path, message = "")
		twitpic_api_url = "http://api.twitpic.com/2/upload.json"
		realm_url = "http://api.twitter.com/"
		auth_provider_url = "https://api.twitter.com/1/account/verify_credentials.json"

		url_token = URI.parse(twitpic_api_url)
		request = Net::HTTP::Post.new(url_token.request_uri)
#
		# construct HTTP request
		boundary = Time.now.strftime("%Y%m%d_%H%M%S_#{$$}")

		#認証用ヘッダ追加
		add_oauth_echo_heder(request,realm_url,auth_provider_url)

		#ヘッダ準備
		request["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
#
		#Bodyの準備はじまり
		body_part = []
		#TwitPicのAPI KEY情報を埋め込む
		add_form_body(body_part,boundary,'key',@twitpic_api_key)
		#メッセージを埋め込む
		add_form_body(body_part,boundary,'message',message) if(message!="")
		#画像を埋め込む
		add_file_body(body_part,boundary,'media',image_file_path)

		#おわり
		body_part << "--#{boundary}--"
		body_part << ""
		#「\r\n"」区切りで配列を結合して文字列にする
		request.body = body_part.join("\r\n")

		#ヘッダにbodyのサイズを設定
		request["Content-Length"] = request.body.size
#
		begin
			#送りつける
			http = Net::HTTP.new(url_token.host, url_token.port).start
			response = http.request(request)

			#成功したかどうか確認
			retrun_message=JSON.parse(response.body)
			p retrun_message
			return nil  if (retrun_message['text'] != message)
			return retrun_message
		rescue => err
			print_error('twitpic_upload',err)
		end
	end

##補助関数

	def print_error(func_name,err,message='')
		time = Time.now.strftime("%Y/%m/%d %H:%M:%S")
		STDERR.print "#{time}\t[Error:#{func_name}]\t #{err} #{message}\n"
	end

end
